package com.jdiv;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.jdiv.internalClasses.JDivTexture;
import com.jdiv.kernel.JDivResources;


public class FPGManager {

	public List<Pixmap> loadFpg(String path) {
		
		FileInputStream fis = null;
		DataInputStream entrada = null;
		
		List<Pixmap> listaImagenes = new ArrayList<Pixmap>();
		
		byte[] header = new byte[8];

		int code;
		int regSize;
		byte[] name = new byte[32];
		byte[] fpname = new byte[12];
		int width;
		int height;
		
		try {
		

			FileHandle file = Gdx.files.internal(path);
			fis = new FileInputStream(file.file());
			entrada = new DataInputStream(fis);

			// Leo el header
			entrada.read(header);
			while (true) {
				// Leo informacion de la imagen
				code = Integer.reverseBytes(entrada.readInt());
	
				regSize = Integer.reverseBytes(entrada.readInt());
				
				// Leo nombre
				entrada.read(name);
				
				// Leo otro nombre
				entrada.read(fpname);
				
				// Leo ancho y alto de la imagen
				width = Integer.reverseBytes(entrada.readInt());
				height = Integer.reverseBytes(entrada.readInt());

				System.out.println(width + "x" + height + " - codigo: " + code);
				
				Pixmap pixmap = new Pixmap(width,height,Format.RGBA8888);

				// Esta lectura al parecer es un dummy pero hay que hacerla
				entrada.readInt();

				for (int j = 0; j < height; j++)
					for (int i = 0; i < width; i++) {

						// El pixel biene codificado en 4 bytes (BGRA)
						// Invierto los Bytes para que quede en (ARGB)
						int pixel = Integer.reverseBytes(entrada.readInt());
						// Separo el alpha 
						int a = (pixel & 0xff000000);
						// lo llevo al byte menos significativo
						a = (a >> 24) & 0x000000ff;
						// desplazo un byte hacia la izquierda para que queden RGB en los 3 primeros bytes y luego agrego el alpha en el
						// byte menos significativo
						int p = (pixel << 8) | a;
					
						pixmap.drawPixel(i, j, p);
					
					}
				
				listaImagenes.add(pixmap);
	
			}

		} catch (EOFException e) { 
			// TODO Auto-generated catch block
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			
				try {
					if (fis != null)
						fis.close();
					
					if (entrada != null)
						entrada.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
		}
		
		return listaImagenes;
		
	}

	public List<TextureRegion> getRegionList(String path) {

		List<TextureRegion> regionList = new ArrayList<TextureRegion>();
		
		List<Pixmap> pixmapList = this.loadFpg(path);
		
		
		if (pixmapList != null) {
		
			for (int i = 0; i < pixmapList.size(); i++) {
				
				
				Pixmap pixmap = pixmapList.get(i);
				
				int w = this.getProximaPotenciaDe2(pixmap.getWidth());
				int h = this.getProximaPotenciaDe2(pixmap.getHeight());
				
				int tamTextura = (w > h) ? w: h;
				
				Pixmap texturePixmap = new Pixmap(tamTextura, tamTextura, Format.RGBA8888);
				
				texturePixmap.drawPixmap(pixmap, 0, 0);
				
				TextureRegion region = new TextureRegion(new Texture(texturePixmap), 0, 0, pixmap.getWidth(), pixmap.getHeight());
				
				regionList.add(region);
				
				
			}

		}
		
		return regionList;
		
	}

	public List<JDivTexture> getJDivTextureList(String path) {

		List<JDivTexture> regionList = new ArrayList<JDivTexture>();
		
		List<Pixmap> pixmapList = this.loadFpg(path);
		
		
		if (pixmapList != null) {
		
			for (int i = 0; i < pixmapList.size(); i++) {
				
				Pixmap pixmap = pixmapList.get(i);
				
				int w = this.getProximaPotenciaDe2(pixmap.getWidth());
				int h = this.getProximaPotenciaDe2(pixmap.getHeight());
				
				int tamTextura = (w > h) ? w: h;
				
				Pixmap texturePixmap = new Pixmap(tamTextura, tamTextura, Format.RGBA8888);
				
				texturePixmap.drawPixmap(pixmap, 0, 0);
				
				Texture texture = new Texture(texturePixmap);
				
				if (texture != null) {
				
					regionList.add(new JDivTexture(texture));
				
				}
				
				
			}

		}
		
		return regionList;
		
	}

	public int loadFpgJDiv(String path) {

		List<JDivTexture> regionList = new ArrayList<JDivTexture>();
		
		List<Pixmap> pixmapList = this.loadFpg(path);
		
		int fileId = ++JDivResources.listTextures.fileCntr;
		
		if (pixmapList != null) {
		
			for (int i = 0; i < pixmapList.size(); i++) {
				
				Pixmap pixmap = pixmapList.get(i);
				
				int w = this.getProximaPotenciaDe2(pixmap.getWidth());
				int h = this.getProximaPotenciaDe2(pixmap.getHeight());
				
				int tamTextura = (w > h) ? w: h;
				
				Pixmap texturePixmap = new Pixmap(tamTextura, tamTextura, Format.RGBA8888);
				
				texturePixmap.drawPixmap(pixmap, 0, 0);
				
				if (texturePixmap != null) {
				
					int idTexture = JDivResources.listTextures.textureAdd(fileId, new JDivTexture(texturePixmap));
					JDivResources.listTextures.imageAdd(fileId, idTexture, 0, 0, pixmap.getWidth(), pixmap.getHeight());
				
				}
				
				
			}

		}
		
		return fileId;
		
	}

	public int getProximaPotenciaDe2(int n) {

		float p = (float) (Math.log10(n)/Math.log10(2));
		p+= (p - (int) p) > 0 ? 1 : 0;
		p = (int) p;

		return (int) Math.pow(2, p);
		
	}
	
}
